#pragma once

#define _DEBUG
#include "PxPhysicsAPI.h"
#include <iostream>

using namespace physx;

PxFilterFlags contactReportFilterShader(PxFilterObjectAttributes attributes0, PxFilterData filterData0,
                                        PxFilterObjectAttributes attributes1, PxFilterData filterData1,
                                        PxPairFlags &pairFlags, const void *constantBlock, PxU32 constantBlockSize)
{
    PX_UNUSED(attributes0);
    PX_UNUSED(attributes1);
    PX_UNUSED(filterData0);
    PX_UNUSED(filterData1);
    PX_UNUSED(constantBlockSize);
    PX_UNUSED(constantBlock);

    // all initial and persisting reports for everything, with per-point data
    pairFlags = PxPairFlag::eSOLVE_CONTACT | PxPairFlag::eDETECT_DISCRETE_CONTACT | PxPairFlag::eNOTIFY_TOUCH_FOUND | PxPairFlag::eNOTIFY_TOUCH_PERSISTS | PxPairFlag::eNOTIFY_CONTACT_POINTS;
    return PxFilterFlag::eDEFAULT;
};

class CollisionCallback : public PxSimulationEventCallback
{
public:
    virtual void onContact(const PxContactPairHeader &pairHeader, const PxContactPair *pairs, PxU32 nbPairs) override
    {

        for (PxU32 i = 0; i < nbPairs; ++i)
        {
            const PxContactPair &pair = pairs[i];
            if (pair.events & PxPairFlag::eNOTIFY_TOUCH_FOUND)
            {
                PxActor *actor0 = pairHeader.actors[0];
                PxActor *actor1 = pairHeader.actors[1];

                std::cout << "Collision detected between: "
                          << actor0->getName() << " and "
                          << actor1->getName() << std::endl;
            }
        }
    }
    virtual void onTrigger(PxTriggerPair *pairs, PxU32 count) override {}
    virtual void onConstraintBreak(PxConstraintInfo *constraints, PxU32 count) override {}
    virtual void onWake(PxActor **actors, PxU32 count) override {}
    virtual void onSleep(PxActor **actors, PxU32 count) override {}
    virtual void onAdvance(const PxRigidBody *const *bodyBuffer, const PxTransform *poseBuffer, const PxU32 count) {}
};